home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickDraw GX / Programming Stuff / Sample Code / Printing Samples / Printer Drivers… / Generic LW "30 sec Alert" / ChooserSupport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-10  |  9.0 KB  |  317 lines  |  [TEXT/MPS ]

  1. /*
  2.     ChooserSupport.c - C code for PACK and LDEF resources used by the Chooser.
  3.     
  4.     8/28/94 - dmh - Finalized and universalized for the SDK.
  5.    12/18/93 - dmh - Updated for the b3 seed.  Fixed highlighting (BitClr) bug.
  6.     9/13/93 - dmh - Modified for the b2 seed.
  7.     4/26/93 - dmh - Modified for the b1 seed.
  8.     
  9.     Copyright © 1992-1994 Apple Computer, Inc.
  10.     All rights reserved.
  11. */
  12.  
  13. #include <Types.h>
  14. #include <QuickDraw.h>
  15. #include <Fonts.h>
  16. #include <Lists.h>
  17. #include <Devices.h>
  18. #include <Resources.h>
  19. #include <Script.h>
  20. #include <ToolUtils.h>
  21. #include <LowMem.h>
  22.  
  23. #include <graphics routines.h>
  24. #include <PrintingDrivers.h>
  25.  
  26. // ------------------------------------------------------------------------
  27. // INTERNAL DEFINES
  28. // ------------------------------------------------------------------------
  29. // Chooser initialize message selector
  30. #define initializeMsg    11
  31.  
  32. // Icon Suite support
  33. #define ttNone        0x0000
  34. #define ttDisabled    0x0001
  35. #define    ttOffline    0x0002
  36. #define ttOpen        0x0003
  37. #define ttSelected     0x4000
  38. #define ttSelectedDisabled    (ttSelected + ttDisabled)
  39. #define ttSelectedOffline    (ttSelected + ttOffline)
  40. #define ttSelectedOpen        (ttSelected + ttOpen)
  41.  
  42. #define ttLabel0    0x0000
  43. #define ttLabel1    0x0100
  44. #define ttLabel2    0x0200
  45. #define ttLabel3    0x0300
  46. #define ttLabel4    0x0400
  47. #define ttLabel5    0x0500
  48. #define ttLabel6    0x0600
  49. #define ttLabel7    0x0700
  50. pascal OSErr PlotIconSuite(const Rect * theRect, short align, short iconTransform, Handle cIcon)
  51.     = {0x303C, 0x0603, 0xABC9};
  52.  
  53. // Copy of the DrawText trap
  54. pascal void OldDrawText(const void *textBuf,short firstByte,short byteCount)
  55.     = 0xA885; 
  56.  
  57. // ------------------------------------------------------------------------
  58. // MAIN CODE FOR PACK
  59. // ------------------------------------------------------------------------
  60. pascal OSErr Device(short message, short caller, StringPtr objName, 
  61.                     StringPtr zoneName, ListHandle theList, long p2)
  62. {
  63.     
  64.     OSErr            anErr = noErr;
  65.     extern Str31     gDriverName;
  66.     StringPtr        pDriverName = &gDriverName;
  67.     extern gxJob    gJob;                        // Declared in our .a file.
  68.     gxJob            *pJob = &gJob;
  69.  
  70.     if (message == initializeMsg)    // InitializeMsg--start up GX
  71.     {
  72.         FCBPBRec    pb;
  73.  
  74.     /*
  75.         Get the name of our driver for GXHandleChooserMessage.
  76.         (The user may have renamed us.)
  77.     */
  78.         pb.ioCompletion     = nil;
  79.         pb.ioNamePtr         = pDriverName;
  80.         pb.ioVRefNum         = 0;
  81.         pb.ioRefNum         = CurResFile();
  82.         pb.ioFCBIndx         = 0;
  83.         anErr = PBGetFCBInfo(&pb, false);
  84.  
  85.     /*
  86.         Clear *pJob, because it hasn't been initialized yet.  That doesn't
  87.         happen until we pass GXHandleChooserMessage an initializeMsg.
  88.     */
  89.         *pJob = nil;
  90.  
  91.     /*
  92.         We need to initialize GX printing so that we can call
  93.         GXHandleChooserMessage.  Since printing requires a graphics
  94.         client, call GXEnterGraphics first.  If there are errors,
  95.         (for example, due to memory limitations), post an alert.
  96.     */
  97.         if (anErr == noErr)
  98.         {
  99.             GXEnterGraphics();
  100.             anErr = GXGetGraphicsError(nil);
  101.             if (anErr == noErr)
  102.             {
  103.                 anErr = GXInitPrinting();
  104.                 if (anErr != noErr)
  105.                     GXExitGraphics();
  106.             }
  107.                 
  108.             if (anErr != noErr)
  109.                 StopAlert(-4095, nil);
  110.         }
  111.     }
  112.  
  113. /*
  114.     If the Chooser hasn't created a job yet, do nothing unless we were
  115.     sent an initializeMsg.  In its default implementation of
  116.     GXHandleChooserMessage, QuickDraw GX will create the job for our
  117.     driver when it receives an initializeMsg.  It will store a reference
  118.     to it in our pJob pointer.
  119.     
  120.     For all other messages, if a job has been created, call
  121.     GXHandleChooserMessage to handle things.
  122. */
  123.     if (anErr == noErr)
  124.     {
  125.         if ((*pJob != nil) || (message == initializeMsg))
  126.         {
  127.             anErr = GXHandleChooserMessage(pJob, pDriverName, message, caller, objName, zoneName, theList, p2);
  128.     
  129.         /*
  130.             If we just got a terminateMsg, and p2 is also terminateMsg, the
  131.             Chooser is closing.  QuickDraw GX just disposed of the gxJob it
  132.             created earlier when GXHandleChooserMessage was passed
  133.             initializeMsg, so we just need to call GXExitPrinting and
  134.             GXExitGraphics to clean up.
  135.             
  136.             Note that we must test the p2 parameter, because the Chooser
  137.             can also send terminateMsg when it wants to empty the device
  138.             list, but not dispose of us.  For example, this will happen
  139.             when the user turns off AppleTalk in the Chooser.
  140.         */
  141.             if ((message == terminateMsg) && (p2 == terminateMsg))
  142.             {
  143.                 GXExitPrinting();
  144.                 GXExitGraphics();
  145.             }
  146.         }
  147.     }
  148.         
  149.     return(anErr);
  150.     
  151. } // Device
  152.  
  153.  
  154.  
  155. // ------------------------------------------------------------------------
  156. // ENTRY POINT FOR LDEF
  157. // ------------------------------------------------------------------------
  158.  
  159. pascal void LDEF(
  160.     short         message,        // What operation to perform on list
  161.     Boolean     select,            // Is this cell to be selected or not?
  162.     Rect        *theRect,        // Rectangle of this cell, clipped to window
  163.     Cell        theCell,        // Which cell this is
  164.     short        dataOffset,        // Offset into data for this cell
  165.     short        dataLen,        // Length of data for this cell
  166.     ListHandle    theList)        // The list to act upon
  167. /*
  168.     An LDEF that works in two modes:
  169.         - if the first two characters of the cell are valid AppleTalk NBP names (ie, not ≈ ≈)
  170.           then the LDEF is just a basic text LDEF
  171.         - otherwise, it assumes the data is part of a PortListRec, which is
  172.           a structure for icons with text underneath
  173. */
  174.  
  175. {
  176. #pragma unused (theCell, dataLen)
  177.  
  178.     gxPortListRec        theCellContents;
  179.     Rect                iconRect;
  180.     unsigned char        hiliteMode;
  181.     
  182.     switch (message)
  183.         {
  184.         case lDrawMsg:
  185.         case lHiliteMsg:
  186.         
  187.             // save the data to avoid locking things down
  188.             if (dataLen > sizeof(theCellContents) )
  189.                 dataLen = sizeof(theCellContents);
  190.             BlockMove(((*(**theList).cells) + dataOffset), &theCellContents, dataLen );
  191.             
  192.             // draw the cell as an icon, but only if we see our magic marker at the front
  193.             if ( (theCellContents.firstMarker == '≈') && (theCellContents.secondMarker == '≈') )
  194.                 {
  195.                 // center the icon rect on the list with a top margin of 10 pixels
  196.                 iconRect.top = theRect->top + 10;
  197.                 iconRect.left = theRect->left + ((theRect->right - theRect->left) >> 1) - 16;
  198.                 iconRect.bottom = iconRect.top + 32;
  199.                 iconRect.right = iconRect.left + 32;
  200.                 
  201.                 
  202.                 // draw the icon
  203.                 if (theCellContents.iconSuiteHandle != nil)
  204.                     PlotIconSuite(&iconRect,
  205.                             ttNone, (select) ? ttSelected: ttNone,
  206.                             theCellContents.iconSuiteHandle);
  207.                             
  208.                 // Get the general area under the icon in which to draw the label
  209.                 iconRect.left = theRect->left + 2;
  210.                 iconRect.right = iconRect.left + (**theList).cellSize.h - 2;
  211.                 iconRect.top = iconRect.bottom + 2;
  212.                 iconRect.bottom = theRect->bottom;
  213.     
  214.                 // use a nice small font for the label            
  215.                 TextFont(applFont);
  216.                 TextSize(9);
  217.                 
  218.                     {
  219.                     short        labelWidth;
  220.                     short        rectWidth;
  221.                     short        labelHeight;
  222.                     FontInfo    theInfo;
  223.                 
  224.                     // Get rid of any text that was there before
  225.                     EraseRect(&iconRect);
  226.                     iconRect.top += 2;
  227.                     
  228.                     // compute the height of the label                    
  229.                     GetFontInfo(&theInfo);
  230.                     labelHeight = theInfo.ascent + theInfo.leading;
  231.                     
  232.                     // compute where to draw the text
  233.                     iconRect.bottom = iconRect.top + labelHeight;
  234.                     rectWidth = iconRect.right-iconRect.left;
  235.                     
  236.                     // truncate the string to fit within the box
  237.                     TruncString(rectWidth, theCellContents.iconName, smTruncEnd);
  238.                     
  239.                     // compute the new width of the string
  240.                     labelWidth = StringWidth(theCellContents.iconName);
  241.                     
  242.                     // center the string, draw it
  243.                     iconRect.left += (rectWidth >> 1) - (labelWidth >> 1);
  244.                     MoveTo(iconRect.left, iconRect.bottom);
  245.                     DrawString(theCellContents.iconName);
  246.                     
  247.                     if (select)
  248.                         {
  249.                         // compute right and lower edge of box bounding the text we just drew
  250.                         iconRect.right = iconRect.left + labelWidth;
  251.                         iconRect.bottom += theInfo.descent;
  252.                         
  253.                         // outset it, and invert it to select it
  254.                         InsetRect(&iconRect, -1, -1);
  255.                         hiliteMode = LMGetHiliteMode();
  256.                         BitClr(&hiliteMode, pHiliteBit);
  257.                         LMSetHiliteMode(hiliteMode);
  258.                         InvertRect(&iconRect);
  259.                         }
  260.                     }
  261.                     
  262.                 TextFont(applFont);
  263.                 TextSize(0);
  264.                 }
  265.             else
  266.                 {
  267.                 // how boring!  It's only text
  268.                 FontInfo    theInfo;
  269.                 Rect        ourRect;
  270.                 short        cellWidth;
  271.                 
  272.                 // add a margin to the rectangle
  273.                 ourRect = *theRect;
  274.                 ourRect.left += 4;
  275.                 --ourRect.right;
  276.                 cellWidth = ourRect.right - ourRect.left;
  277.                 
  278.                 // erase the rectangle
  279.                 GetFontInfo(&theInfo);
  280.                 EraseRect(theRect);
  281.                 MoveTo(ourRect.left, ourRect.bottom - theInfo.descent);
  282.                 
  283.                 // hey, you can't park that string here -- it's too big!
  284.                 if (TextWidth((Ptr) &theCellContents, 0, dataLen) > cellWidth )
  285.                     {
  286.                     // condense the text first
  287.                     TextFace(condense);
  288.                     
  289.                     // then truncate afterwards
  290.                     TruncText(cellWidth, (Ptr) &theCellContents, &dataLen, smTruncEnd);
  291.                     }
  292.                     
  293.                 // those darn other languages!
  294.                 if (GetSysJust() == teJustRight)
  295.                     Move(cellWidth-TextWidth((Ptr) &theCellContents, 0, dataLen) , 0);
  296.                     
  297.                 OldDrawText((Ptr) &theCellContents, 0, dataLen);
  298.                 
  299.                 // if selected, invert it
  300.                 if (select)
  301.                     {
  302.                     hiliteMode = LMGetHiliteMode();
  303.                     BitClr(&hiliteMode, pHiliteBit);
  304.                     LMSetHiliteMode(hiliteMode);
  305.                     InvertRect(theRect);
  306.                     }
  307.                     
  308.                 // normal text again
  309.                 TextFace(normal);
  310.                 }
  311.                 
  312.             break;
  313.             
  314.         } // switch
  315.         
  316. } // LDEF
  317.